Java集合(13)--LinkedHashMap源码分析

HashMap使用哈希表来存储数据,并用拉链法来处理冲突。LinkedHashMap继承自HashMap,同时自身有一个链表,使用链表存储数据,不存在冲突。

LinkedList和LinkedHashMap一样使用一个双向循环链表,但LinkedList存储的是简单的数据,并不是“键值对”。

LinkedList和LinkedHashMap都可以维护内容的顺序,但HashMap不维护顺序。

 

 

public class LinkedHashMap<K,V>  
    extends HashMap<K,V>  
    implements Map<K,V>  

 

HashMap的init方法没有实现,但是LinkedHaqshMap已经对其实现:

 

void init() {  
//初始化一个Entry类型的header  
        header = new Entry<K,V>(-1, null, null, null);        
header.before = header.after = header;  
    }

 

LinkedHashMap中多了一个accessOrder变量,他表示迭代时候的一个顺序,若为true,则按照读取顺序排序(读得越多在链表的越后面读得越少在链表的越前面LRU,最近最少使用),若为false则按照插入顺序排序.LinkedHaqshMap的前4个构造方法可以看出,accessOrder默认为false,故按照插入顺序进行排序。

 

 void recordAccess(HashMap<K,V> m) {  
           LinkedHashMap<K,V> lm = (LinkedHashMap<K,V>)m;  
           if (lm.accessOrder) {  
               lm.modCount++;  
               remove();  
               addBefore(lm.header);  
           }  
       }  

 

LRU算法中,最少使用的页面被先换出最近使用的很可能以后还会使用

他判断accessOrder属性,若为true,则执行一个叫做LRU的算法,将刚访问的entry移除,然后加到header前面,这样迭代的时候会优先迭代最近频繁访问的entry(不是链表头),从而就改变了迭代的顺序。

 

void addEntry(int hash, K key, V value, int bucketIndex) {
      createEntry(hash, key, value, bucketIndex);
      Entry<K,V> eldest = header.after;
      if (removeEldestEntry(eldest)) {
          removeEntryForKey(eldest.key);
      } else {
          if (size >= threshold)
              resize(2 * table.length);
      }
 }

 

protected boolean removeEldestEntry(Map.Entry<K,V> eldest) {
   //始终返回的是false     
return false; }

 

 

启发:若希望将Map当做Cache来使用,并且限制大小,只需继承LinkedHashMap并重写removeEldestEntry(Entry<K,V> eldest)方法,像这样:

private static final int MAX_ENTRIES = 100;
 protected boolean removeEldestEntry(Map.Entry eldest) {
      return size() > MAX_ENTRIES;
 }

 

实现最近被使用(LRU)缓存:

 

import java.util.LinkedHashMap;
import java.util.Map;
 
public LRUCache<K, V> extends LinkedHashMap<K, V> {
  private int cacheSize;
 
  public LRUCache(int cacheSize) {
    super(16, 0.75, true);//排序策略
    this.cacheSize = cacheSize;
  }

 

posted @ 2015-08-17 23:02  山野豪杰  阅读(165)  评论(0编辑  收藏  举报